package org.termine.db;

import java.sql.Connection;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ManagedBean
@ApplicationScoped
public class Connector {

	private static final Logger logger = LoggerFactory.getLogger(Connector.class);

	protected DataSource dataSource;
	protected PoolProperties poolProperties;

	public Connector(){
		logger.info("connecting to database");
		try{
			PoolProperties p = new PoolProperties();
			p.setUrl("jdbc:db2://vampir.cosy.sbg.ac.at:50001/DBVWS12");
			p.setDriverClassName("com.ibm.db2.jcc.DB2Driver");
			p.setUsername("jaltenr");
			p.setPassword("al239ghzgxw");
			p.setRemoveAbandonedTimeout(120);
			p.setRemoveAbandoned(true);
			p.setDefaultAutoCommit(false);
			p.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
			p.setJdbcInterceptors(
					"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
					"org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");

			this.dataSource = new DataSource();
			this.dataSource.setPoolProperties(p);
		}catch (Exception e){
			logger.error("failed to connect to database", e);
			this.dataSource = null;
		}
	}

	public void rollback(Connection connection){
		logger.info("rollback");
		if (connection == null){
			logger.warn("rollback called, but the connecton is null");
		}
		else{
			try{
				connection.rollback();
				this.closeConnection(connection);
			}catch (Exception e){
				logger.warn("error during rollback", e);
			}
		}
	}

	public void commit(Connection connection) throws Exception{
		logger.info("commit");
		if (connection == null){
			throw new Exception("commit called, but connection is null");
		}
		else{
			connection.commit();
			this.closeConnection(connection);
		}
	}

	public void closeConnection(Connection connection){
		logger.debug("closing connection");
		if (connection == null){
			logger.warn("closeConnection: connection is null");
		}
		else{
			try{
				connection.close();
			}catch (Exception e){
				logger.warn("error closing connection", e);
			}
		}
	}

	public Connection getConnection() throws Exception {
		logger.trace("getConnection called");

		if (this.dataSource == null){
			logger.info("dataSource is null, this means there has previously been an error establishing a connection, attempting to reconnect");
			this.dataSource = new Connector().dataSource;
		}
		if (this.dataSource == null){
			throw new Exception("no database connection");
		}
		Connection newConnection = this.dataSource.getConnection();
		return newConnection;
	}

}